package com.xunmall.wechat.controller;

import com.xunmall.wechat.model.constant.WeChatLinkConstant;
import com.xunmall.wechat.model.message.event.ClickEvent;
import com.xunmall.wechat.model.message.event.SubscribeEvent;
import com.xunmall.wechat.model.message.req.*;
import com.xunmall.wechat.service.impl.*;
import com.xunmall.wechat.util.MessageUtils;
import com.xunmall.wechat.util.wechat.WeiXinCheckUtils;
import com.xunmall.wechat.util.wechat.security.AesUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * Created by wangyanjing on 2018/11/1.
 */
@Controller
@RequestMapping("/server")
@Slf4j
public class WeChatController extends BaseWeChatController {

    @Autowired
    private TextMessageService textMessageService;
    @Autowired
    private LocationMessageService locationMessageService;
    @Autowired
    private ImageMessageService imageMessageService;
    @Autowired
    private LinkMessageService linkMessageService;
    @Autowired
    private VoiceMessageService voiceMessageService;
    @Autowired
    private DefaultEventService defaultEventService;

    @RequestMapping(value = "/wx", method = RequestMethod.GET)
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        log.info("响应参数为：signature{},timestamp{},nonce{},echostr {}", signature,
                timestamp, nonce, echostr);
        if (WeiXinCheckUtils.checkSignature(signature, timestamp, nonce)) {
            write(echostr, response);
        }
    }

    @RequestMapping(value = "/wx", method = RequestMethod.POST)
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        /* 从请求中获得xml格式的信息。并转化为map类型 */
        String channel = parseDomain(request);
        Map<String, String> map = MessageUtils.parseXml(request);
        if ("aes".equals(request.getParameter("encrypt_type"))) {
            /* 获得解密后的消息正文 */
            String mingwenXML = AesUtils.descMessage(map.get("Encrypt"), request.getParameter("msg_signature"), request.getParameter("timestamp"), request.getParameter("nonce"));
            map = MessageUtils.xmlToMap(mingwenXML);
        }
        String fromUserName = map.get("FromUserName");// 发送方帐号（一个OpenID）
        String toUserName = map.get("ToUserName");// 开发者微信号
        String msgType = map.get("MsgType");// text//如果是文本消息的话，MsgType="text"
        String createTime = map.get("CreateTime");// 文本创建时间
        String message = null;
        // 判断是否为文本消息
        if (WeChatLinkConstant.REQ_MESSAGE_TYPE_TEXT.equals(msgType)) {
            String msgId = map.get("MsgId");// 文本ID
            String content = map.get("Content");
            TextMessage text = new TextMessage();
            text.setFromUserName(fromUserName);
            text.setToUserName(toUserName);
            text.setMsgType(msgType);
            text.setMsgId(Long.parseLong(msgId));
            text.setCreateTime(Long.parseLong(createTime));
            text.setContent(content);
            message = textMessageService.convertTextMessage(text);
        }
        // 判断是否为图片消息
        if (WeChatLinkConstant.REQ_MESSAGE_TYPE_IMAGE.equals(msgType)) {
            String content = map.get("PicUrl");
            ImageMessage text = new ImageMessage();
            text.setFromUserName(fromUserName);
            text.setToUserName(toUserName);
            text.setMsgType(msgType);
            text.setCreateTime(Long.parseLong(createTime));
            text.setPicUrl(content);
            message = imageMessageService.convertImageMessage(text);
        }
        // 判断是否为连接消息
        if (WeChatLinkConstant.REQ_MESSAGE_TYPE_LINK.equals(msgType)) {
            String title = map.get("Title");
            String description = map.get("Description");
            String url = map.get("Url");
            LinkMessage text = new LinkMessage();
            text.setFromUserName(fromUserName);
            text.setToUserName(toUserName);
            text.setMsgType(msgType);
            text.setCreateTime(Long.parseLong(createTime));
            text.setTitle(title);
            text.setDescription(description);
            text.setUrl(url);
            message = linkMessageService.convertLinkMessage(text);
        }
        // 判断是否为地理位置消息
        if (WeChatLinkConstant.REQ_MESSAGE_TYPE_LOCATION.equals(msgType)) {
            String location_x = map.get("Location_X");
            String location_y = map.get("Location_Y");
            String scale = map.get("Scale");
            String label = map.get("Label");
            LocationMessage text = new LocationMessage();
            text.setFromUserName(fromUserName);
            text.setToUserName(toUserName);
            text.setMsgType(msgType);
            text.setCreateTime(Long.parseLong(createTime));
            text.setLocation_X(location_x);
            text.setLocation_Y(location_y);
            text.setScale(scale);
            text.setLabel(label);
            message = locationMessageService.convertLocationMessage(text);
        }
        // 判断是否为音频消息
        if (WeChatLinkConstant.REQ_MESSAGE_TYPE_VOICE.equals(msgType)) {
            String mediaId = map.get("MediaId");
            String format = map.get("Format");
            VoiceMessage text = new VoiceMessage();
            text.setFromUserName(fromUserName);
            text.setToUserName(toUserName);
            text.setMsgType(msgType);
            text.setCreateTime(Long.parseLong(createTime));
            text.setMediaId(mediaId);
            text.setFormat(format);
            message = voiceMessageService.convertVoiceMessage(text);
        }
        // 判断是否为推送消息
        if (WeChatLinkConstant.REQ_MESSAGE_TYPE_EVENT.equals(msgType)) {
            String eventType = map.get("Event");
            if (WeChatLinkConstant.EVENT_TYPE_SUBSCRIBE.equals(eventType)) {
                String eventKey = map.get("EventKey");
                SubscribeEvent event = new SubscribeEvent();
                event.setFromUserName(fromUserName);
                event.setToUserName(toUserName);
                event.setMsgType(msgType);
                event.setCreateTime(Long.parseLong(createTime));
                event.setEventKey(eventKey);
                message = defaultEventService.handlerSubscribeEvent(event, channel);
            }
            if (WeChatLinkConstant.EVENT_TYPE_UNSUBSCRIBE.equals(eventType)) {
                BaseMessage event = new BaseMessage();
                event.setFromUserName(fromUserName);
                event.setToUserName(toUserName);
                event.setCreateTime(Long.parseLong(createTime));
                message = defaultEventService.handlerUnSubscribeEvent(event);
            }
            if (WeChatLinkConstant.EVENT_TYPE_CLICK.equals(eventType)) {
                String eventKey = map.get("EventKey");
                ClickEvent event = new ClickEvent();
                event.setFromUserName(fromUserName);
                event.setToUserName(toUserName);
                event.setMsgType(msgType);
                event.setCreateTime(Long.parseLong(createTime));
                event.setEventKey(eventKey);
                message = defaultEventService.handlerClickEvent(event);
            }
            if (WeChatLinkConstant.EVENT_TYPE_VIEW.equals(eventType)) {
                String eventKey = map.get("EventKey");
                ClickEvent event = new ClickEvent();
                event.setFromUserName(fromUserName);
                event.setToUserName(toUserName);
                event.setMsgType(msgType);
                event.setCreateTime(Long.parseLong(createTime));
                event.setEventKey(eventKey);
                message = defaultEventService.handlerViewEvent(event);
            }
        }
        System.out.println("请求参数：" + map.toString());
        System.out.println("响应信息：" + message);
        if ("aes".equals(request.getParameter("encrypt_type"))) {
            message = AesUtils.aescMessage(message, request.getParameter("timestamp"), request.getParameter("nonce"));
        }
        write(message, response);
    }

}
